package com.tilaiedu.mvc.config;

import com.tilaiedu.mvc.exception.GlobalException;
import com.tilaiedu.mvc.interceptor.PermissionInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;

import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @Author xlzhang
 * @Date 2022/5/25 9:33
 * @Version 1.0
 * @Description TODO
 */
@Configuration
@ComponentScan({"com.tilaiedu.mvc.controller","com.tilaiedu.mvc.handler"})
// 开启springmvc的注解驱动，默认加载web应用的相关组件，比如消息转换器
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {

    /**模板解析器 */
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setCacheable(false);
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setOrder(1);
        return templateResolver;
    }

    /** 模板引擎 */
    @Bean
    public SpringTemplateEngine springTemplateEngine(SpringResourceTemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    /** 视图解析器 */
    @Bean
    public ThymeleafViewResolver viewResolver(SpringTemplateEngine springTemplateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(springTemplateEngine);
        viewResolver.setCharacterEncoding("UTF-8");
        return viewResolver;
    }

    // 配置文件上传
    // 文件上传的解析器必须固定注入容器的id名称为 multipartResolver
    @Bean("multipartResolver")
    public MultipartResolver multipartResolver(){
        /**
         * StandardServletMultipartResolver是基于servlet3.1原生上传组件封装的
         * 上传参数需要在web.xml或WebInit中配置
         */
        return new StandardServletMultipartResolver();
    }

    // 这个静态资源的配置会影响404异常的统一配置
    // 让tomcat的默认sevlet来处理静态资源
    // @Override
    // public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    //     // 开启静态资源的默认处理器(Tomcat default aservlet)
    //     configurer.enable();
    // }

    // 这种方式，就是配置springmvc来处理静态资源，设置后，springmvc会自动创建一个资源的对应控制器方法处理静态
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // patchPatterns 这个参数就相当于在浏览器输入的资源路径
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 只能处理date类型
        DateFormatter formatter = new DateFormatter();
        formatter.setFallbackPatterns("yyyy-MM-dd","yyyy-MM-dd HH:mm:ss");
        registry.addFormatter(formatter);
        // 配置JDK8的新日期API
        final DateTimeFormatterRegistrar formatterRegistrar =
                new DateTimeFormatterRegistrar();
        formatterRegistrar.setTimeFormatter(DateTimeFormatter.ofPattern("HH:mm:ss"));
        formatterRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        formatterRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        formatterRegistrar.registerFormatters(registry);
    }

    /**
     * 注册拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器，设置拦截的资源路径
        registry.addInterceptor(new PermissionInterceptor())
                //  /** 代表拦截所有请求资源
                .addPathPatterns("/**")
                // 那些资源不需要拦截，可以设置这个排除选项
                .excludePathPatterns("/login.html","/login","/captcha","/static/**");
    }

    // 配置视图控制器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // urlPathOrPattern  就是在浏览器输入的资源路径
        // 表示当前在浏览器输入的资源路径为  / 去加载login页面，这里也是写简写，会自动调用视图解析器拼接前缀和后缀
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/login.html").setViewName("login");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/dataList.html").setViewName("dataList");
        registry.addViewController("/500.html").setViewName("500");
    }

    // 统一异常处理的配置
    // @Override
    // public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    //     resolvers.add(0,new GlobalException());
    // }
}
